home *** CD-ROM | disk | FTP | other *** search
- /* this is a little utility used
- to backup files compressed by pkzip to a disk
-
- the first argument is the name of the diskdrive to use for backup
-
- if no other arguments are given:
-
- it first compresses all files in the current directory (which can
- be the root) to a file root.zip and stores this file to disk
-
- then it compresses all directories, one by one, and stores these
- to disk
-
- if other arguments are given they are compressed one by one and stored
- to disk
-
- when storing a zipped file, it splits the file into parts on separate
- disks if necessary. These parts are called name.p# where # is a
- number from 1 to 99. The last part is called name.-#
- They can easily be restored.
-
- normally the program signals only when it needs a new disk.
- it deletes anything on the disk and calls a format program if necessary
-
- */
- #include <time.h>
- #include <conio.h>
- #include <dos.h>
- #include <dir.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <alloc.h>
- #include <io.h>
- #include <errno.h>
- #include <sys\stat.h>
-
- #define true 1
- #define false 0
-
-
- #define ROOTFILES 1
- #define DIRFILES 2
- #define SINGLEFILE 3
-
-
- int dnum = 0; /* current backup disk */
-
- char zipdir[64];
- char zipname[128];
- char zipsname[18];
-
- char cmdline[128];
- char drive = 'A';
- char *buf;
-
- typedef struct his {char s[128]; struct his * n;} his;
-
- struct his * history = NULL, *th;
-
- char bleepkey()
- {
- time_t tp, tn;
-
- while(! kbhit()){
- sound(600);delay(100);nosound();delay(100);
- sound(600);delay(100);nosound();delay(100);
- sound(600);delay(100);nosound();delay(100);
- sound(860);delay(400);nosound();
-
- (void) time(&tp);
-
- do (void)time(&tn); while((! kbhit()) && (tn - tp < 4));
- }
- return getch();
- }
-
-
- int askcontin()
- {
- char c;
-
- for(;;){
- fprintf(stdout, "Continue? (n)o [y]es ");
- c = bleepkey();
- switch(c){
- case 10: case 13: case 'y': case 'Y': puts("YES"); return true;
- case 'n': case 'N': puts("NO"); return false;
- otherwise: break;
- }
- }
- }
-
- void deletedir(char *path){
- char spath[128];
- char npath[128];
- struct ffblk fs;
-
- strcpy(spath, path);
- strcat(spath, "*.*");
-
- if(findfirst(spath, &fs, FA_DIREC) == 0){
- do{
- if(fs.ff_attrib & FA_DIREC){
- if(fs.ff_name[0] != '.'){
- strcpy(npath, path);
- strcat(npath, fs.ff_name);
- strcat(npath, "\\");
- deletedir(npath);
- strcpy(npath, path);
- strcat(npath, fs.ff_name);
- puts(npath);
- if(rmdir(npath) != 0) perror("Ignored delete directory error: ");
- }
- }
- else{
- strcpy(npath, path);
- strcat(npath, fs.ff_name);
- puts(npath);
- if(remove(npath)!= 0) if(errno == EACCES){
- chmod(npath, S_IREAD | S_IWRITE);
- if(remove(npath) != 0) perror("Ignored delete file error: ");
- }
- }
- }while(findnext(&fs) == 0);
- }
- }
-
-
-
-
-
-
-
- void cleandisk(){
- char spath[10];
-
- struct ffblk fs;
-
- strcpy(spath, "x:\\*.*");
- spath[0] = drive;
-
- if(findfirst(spath, &fs, FA_DIREC) == 0){
- fprintf(stdout, "Deleting existing files %s\n", spath);
- strcpy(spath, "x:\\");
- spath[0] = drive;
- deletedir(spath);
- }
- }
-
- int getinsertnew(){
- char c;
-
- char fcmd[20];
- char t[3];
-
-
- dnum++;
-
- strcpy(fcmd, "format ");
- strcpy(t, "x:");
- t[0] = drive;
- strcat(fcmd, t);
-
-
- for(;;){
- fprintf(stdout, "Insert new backup disk %d in drive %c\nALL EXISTING FILES WILL BE DELETED\n", dnum, drive);
- fprintf(stdout, "Enter (f)ormat (s)top [c]ontinue ");
-
- c = bleepkey();
-
- switch(c){
- case 'f': case 'F': puts("FORMAT"); system(fcmd); break;
- case 's': case 'S': puts("STOP"); return false;
- case 13: case 10: case 'c': case 'C': puts("CONTINUE"); cleandisk(); return true;
- }
- }
- }
-
-
- long df()
- {
- int cnt = false;
- int dr;
- struct dfree free;
-
- /* we need to know drive free space */
-
- dr = (int)(drive - 'A') + 1;
-
- do{
- getdfree(dr, &free);
- if(free.df_sclus == 0xFFFF){
- fprintf(stderr, "Can not get drive free space for %c\n", drive);
- cnt = askcontin();
- if(!cnt) return -1L;
- }
- }while(cnt);
-
- return (long) free.df_avail
- * (long) free.df_bsec
- * (long) free.df_sclus;
- }
-
- #define maxbuf 16384
-
- int splitcopy()
- {
- long avail, filelen, r, w, wrote = 0L, readd = 0L;
- int fn = 0; int zf, czf, ctrl;
- char t[4];
- char zipcopy[20];
-
- /* we need to know length of zipfile */
-
-
-
- zf = _open(zipname, O_RDONLY | O_BINARY);
-
- /* ctrl = ioctl(zf, 0);
- ioctl(zf, 1, (ctrl | 0x20) & 0xff); */ /* no ^Z intervention! */
-
- if(zf < 0){
- fprintf(stderr, "Can not open %s for reading\n", zipname);
- exit(-1);
- }
-
- filelen = filelength(zf);
-
- for(;;){
- /* available on disk */
- avail = df();
-
- /* if error */
- if(avail < 0){
- close(zf);
- return false;
- }
-
- if(avail == 0) if(! getinsertnew()){ close(zf); return false; }
-
- printf("Drive %c: has %ld bytes available\n", drive, avail);
-
-
- strcpy(zipcopy, "x:\\");
- zipcopy[0] = drive;
- strcat(zipcopy, zipsname);
-
- if((fn == 0) && (filelen <= avail))
- strcat(zipcopy, ".zip");
- else{
- if((filelen - readd) < avail)
- strcat(zipcopy, ".-");
- else
- strcat(zipcopy, ".p");
- fn++;
- strcat(zipcopy, itoa(fn,t,10));
- }
-
- fprintf(stdout, "Creating %s\n", zipcopy);
-
- th = (struct his*) malloc(sizeof(struct his));
- if(th != NULL){
- sprintf(th->s, "%3d %s\n", dnum, zipcopy);
- th->n = history;
- history = th;
- }
-
- czf = open(zipcopy, O_CREAT | O_BINARY | O_RDWR /*, S_IFREG | S_IREAD | S_IWRITE*/ );
-
- if(czf < 0){
- fprintf(stderr, "Can not open %s for writing\n", zipcopy);
- exit(-1);
- }
-
-
- /* what to do with read/write errors??? */
-
- do{
- r = _read(zf, buf, (avail > maxbuf ? maxbuf : avail));
-
- if(r < 0){
- fprintf(stderr, "\nRead error");
- exit(-1);
- }
-
- w = 0L;
- if(r > 0){
- w = _write(czf, buf, r);
- if(r != w){
- fprintf(stderr, "\nWrite error");
- exit(-1);
- }
- }
-
- avail -= w;
- readd += r;
- wrote += w;
- fprintf(stdout, "\rWrote %ld of %ld", wrote, filelen);
- }while((avail > 0L ) && (r == maxbuf));
-
- fprintf(stdout, "\n");
-
- _close(czf);
-
- if(readd == filelen) {
- _close(zf);
- return true;
- }
-
- if(!getinsertnew()){
- close(zf);
- return false;
- }
- }
- }
-
- int compcopy(char * name, int mode)
- {
- char *t;
- int rv;
- struct ffblk fs;
-
- /* if first disk */
- if(dnum == 0) if(!getinsertnew()) return false;
-
- /* extract zipname */
- t = name;
- while(*t) t++;
- t--;
- while((t > name) && (*t != '\\')) t--;
-
- strcpy(zipsname, t);
- t = zipsname;
- while(*t) t++;
- while((t > zipsname) && (*t != '.') && (*t != '\\')) t--;
- if(*t == '.') *t = 0;
-
- if(*zipdir){
- strcpy(zipname, zipdir);
- strcat(zipname, "\\");
- strcat(zipname, zipsname);
- }
- else strcpy(zipname, zipsname);
- strcat(zipname, ".zip");
-
- /* construct pkzip command */
-
- switch(mode){
- case ROOTFILES:
- strcpy(cmdline, "pkzip ");
- strcat(cmdline, zipname);
- strcat(cmdline, " *.*");
- break;
- case DIRFILES:
- strcpy(cmdline, "pkzip -Pr ");
- strcat(cmdline, zipname);
- strcat(cmdline, " ");
- strcat(cmdline, name);
- strcat(cmdline, "\\*.*");
- break;
- case SINGLEFILE:
- strcpy(cmdline, "pkzip ");
- strcat(cmdline, zipname);
- strcat(cmdline, " ");
- strcat(cmdline, name);
- break;
- }
-
- rv = system(cmdline);
-
-
- if(findfirst(zipname, &fs, 0) != 0){
- fprintf(stdout, "No zipfile created! (possibly empty directory or disk full)\n");
- return askcontin();
- }
- else if(rv != 0){
- fprintf(stderr, "PKZIP returned error value %d\n", rv);
- remove(zipname);
- return askcontin();
- }
-
- printf("Now split-copy %s to %c:\n", zipname, drive);
-
- rv = splitcopy();
-
- if(remove(zipname)){
- fprintf(stderr, "Fatal error: Can not remove %s\n", zipname);
- exit(-1);
- }
-
- return rv;
-
- }
-
-
- void printhistory(struct his * history, FILE * t)
- {
- if(history == NULL) return;
- printhistory(history -> n,t);
- fputs(history -> s, stdout);
- fputs(history -> s, t);
- }
-
-
-
-
-
-
-
-
-
- void main(argc, argv)
- int argc;
- char **argv;
- {
- int fspecified = 0;
- struct ffblk fs;
-
- buf = (char *) malloc(maxbuf);
-
- if(buf == NULL){
- fprintf(stderr, "Can not allocate copy buffer, sorry ...");
- exit(-1);
- }
-
- strcpy(zipdir, ".");
-
- if((argc > 1) && (strcmp(argv[1], "-r") == 0)){
- rzip( --argc, ++argv);
- exit(0);
- }
-
- argc--;
- argv++;
-
-
- while(argc--){
- if(argv[0][0] == '-') switch(argv[0][1]){
- case 'd':
- if(strlen(argv) == 2){
- fprintf(stderr, "Need directory name for -d switch\n");
- exit(-1);
- }
- strcpy(zipdir, &argv[0][2]);
- printf("Temporary directory for zipfiles is %s\n", zipdir);
- break;
- otherwise: break;
- }
- else if((strlen(argv[0]) == 2) && (argv[0][1] == ':')){
- drive = toupper(argv[0][0]);
- if(drive > 'B'){
- fprintf(stderr, "drive specification must one of A: or B:\n");
- exit(-1);
- }
- }
- else{
- fspecified = true;
- if(! findfirst(argv[0], &fs, FA_DIREC)){
- if(fs.ff_attrib == FA_DIREC){
- if(!compcopy(argv[0], DIRFILES)) exit(-1);
- }
- else if(!compcopy(argv[1], SINGLEFILE)) exit(-1);
- }
- else{
- fprintf(stderr, "\007File not found %s\n", argv[0]);
- }
- }
- argv++;
- }
-
- if(! fspecified){
- if(!compcopy("root", ROOTFILES)) exit(-1);
- if(! findfirst("*.*", &fs, FA_DIREC)) do{
- if((fs.ff_attrib == FA_DIREC) && (fs.ff_name[0] != '.'))
- if(!compcopy(fs.ff_name, DIRFILES)) exit(-1);
- }while(findnext(&fs) != -1);
- }
-
- if(history != NULL){
- char tn[20];
- FILE *t;
-
- strcpy(tn, "x:\\BZIP.CNT");
- *tn = drive;
-
- t = fopen(tn, "w");
- if(t == NULL){
- fprintf(stderr, "Cannot create table of contents file\n");
- exit(-1);
- }
- fputs("\nTable of contents:\n\n", stdout);
- fputs("Table of contents:\n\n", t);
- printhistory(history, t);
- fclose(t);
- fprintf(stdout, "Table of contents written on %s\n", tn);
- }
- printf("Done, press a a key \n"); bleepkey();
- }
-
-
- /* =============== source for rzip ============== */
-
- rzip(argc,argv)
- int argc;
- char **argv;
- {
- char c, spath[80], drive[3], dir[66], file[9], ext[5], npath[80], zipname[80], *t;
- int fnum = 1, fc, fo, flags, lastfile = false;
- int r, w;
- long tw = 0L;
- struct ffblk fs;
-
- if(argc != 2){
- fprintf(stderr, "Usage: rzip drive:zipname\n");
- exit(-1);
- }
-
- strcpy(spath, argv[1]);
-
- flags = fnsplit(spath, drive, dir, file, ext);
- if((flags & WILDCARDS) || (!(flags & FILENAME))){
- fprintf(stderr, "Illegal filename: %s\n", spath);
- exit(-1);
- }
-
- strcpy(zipname, file);
- strcat(zipname, ".zip");
-
- /* remove extension (if any) from specified name */
- if(flags & EXTENSION)
- spath[strlen(spath) - strlen(ext)] = 0;
-
- printf("Restoring split zipfile %s\n", zipname);
-
- fc = open(zipname, O_CREAT | O_BINARY | O_RDWR, S_IWRITE | S_IREAD);
- if(fc < 0){
- fprintf(stderr, "Cannot open zipfile %s\n", zipname);
- exit(-1);
- }
-
- for(;;){
- do{
- if(fnum == 1)
- printf("Enter first disk: (a)bort [c]ontinue ");
- else
- printf("Enter next disk: (a)bort [c]ontinue ");
- c = toupper(bleepkey());
- switch(c){
- case 10: case 13: case 'C': c= 'C'; puts("CONTINUE"); break;
- case 'A': puts("ABORT"); close(fc); remove(zipname); exit(-1); break;
- }
- }while(c != 'C');
-
- do{
- c = 'D';
- sprintf(npath, "%s.-%d", spath, fnum);
- if(findfirst(npath, &fs, 0) == 0)
- lastfile = true;
- else{
- sprintf(npath, "%s.p%d", spath, fnum);
- if(findfirst(npath, &fs, 0) != 0){
- printf("\007File %s.[p-]%d not found (r)etry (a)bort", spath, fnum);
- c = toupper(bleepkey());
- switch(c){
- case 'R': puts("RETRY"); break;
- case 'A': puts("ABORT"); exit(-1); break;
- otherwise: c = 'R'; break;
- }
- }
- }
- }while(c == 'R');
-
- printf("Copying %s to %s\n", npath, zipname);
-
- fnum++;
- printf("Reading %s\n", npath);
- fo = open(npath, O_RDONLY | O_BINARY);
- if(fo < 0){
- fprintf(stderr, "Can not open file %s\n", npath);
- exit(-1);
- }
-
- do{
- r = _read(fo, buf, maxbuf);
-
- if(r > 0){
- w = _write(fc, buf, r);
- tw += w;
- printf("\rWrote %ld", tw);
- if(w < r){
- fprintf(stderr, "\nwrite error on temporary zipfile");
- close(fo);
- close(fc);
- remove(zipname);
- exit(-1);
- }
- }
- }while(r == maxbuf);
- putchar('\n');
-
- close(fo);
-
- if(lastfile){
- close(fc);
- printf("DONE, Press a key\n");
- bleepkey();
- exit(0);
- }
- }
- }
-